﻿using System;
using System.Collections.Generic;
using System.Text;
using JWFW.Encrypt;
using JWFW.SFL;

namespace JWFW.Model.Register
{
    /// <summary>
    /// 单机注册模块－客户端
    /// </summary>
    public class PCRegisterClient:BaseRegisterClient
    {
        /// <summary>
        /// 单机注册模块－客户端
        /// </summary>
        public PCRegisterClient()
        {

        }

        #region 获取机器码2
        /// <summary>
        /// 获得单机注册的机器码【结果与基类的函数一样】
        /// </summary>
        /// <param name="toolCode">工具的代码</param>
        /// <returns>单机注册的机器码</returns>
        public string GetPCMC2(string toolCode)
        {
            string res = "";
            string mc = g_b64.Decode(this.GetMC2());
            for (int i = 0; i < mc.Length; i++)
            {
                res += mc[i] + (toolCode.Length > i ? toolCode[i].ToString() : "");
            }
            return g_b64.Encode(res);
        }
        /// <summary>
        /// 获取机器码2【结果与基类的函数一样】
        /// </summary>
        /// <returns>客户电脑的机器码</returns>
        protected string GetMC2()
        {
            try
            {
                SetTimer(true);
                return g_b64.Encode(CreateMC2(g_hash["HD"], g_hash["MAC"]));
            }
            finally
            {
                SetTimer(false);
            }
        }
        /// <summary>
        /// 获取机器码的方法2【结果基类的函数一样】
        /// </summary>
        /// <param name="hdId">硬盘序列号</param>
        /// <param name="mac">网卡地址</param>
        /// <returns>交叉运算后的标识客户电脑的机器码</returns>
        protected string CreateMC2(string hdId, string mac)
        {
            SetTimer(true);
            string res = "";
            for (int i = 0, j = mac.Length - 1; i < mac.Length; i++, j--)
            {
                int tmp = char.ConvertToUtf32(mac, i) + char.ConvertToUtf32(hdId, j);
                tmp = tmp % 26 + 65;
                res = char.ConvertFromUtf32(tmp) + res;
            }
            return res;
        }

        #endregion

        #region 解码

        /// <summary>
        /// 解码
        /// 1.B64-2解密，并储存在字典中
        /// 2.remove CRC字符，并存储在字典中
        /// 3.remove expire，并存储在字典中
        /// </summary>
        /// <param name="regCode">待解析的注册码</param>
        /// <returns>除去了CRC字符和Expire字符的解析后的注册码</returns>
        public string ParseRC(string regCode)
        {
            try
            {
                SetTimer(true);
                regCode = g_b64_2.Decode(regCode);
                AddDictioanry("RC", regCode);
                AddDictioanry("F", regCode.Remove(10));
                AddDictioanry("B", regCode.Substring(regCode.Length - 5));
                regCode = regCode.Remove(0, 2);
                regCode = regCode.Remove(regCode.Length - 2);
                regCode = RemoveExpire(regCode);
                return g_b64.Decode(regCode);
            }
            finally
            {
                SetTimer(false);
            }
        }
        /// <summary>
        /// 移除期限，并保存到字典中
        /// </summary>
        /// <param name="origin">待移除期限的注册码【已移除CRC字符】</param>
        /// <returns></returns>
        protected string RemoveExpire(string origin)
        {
            SetTimer(true);
            int div = 2;
            int times = 3;
            int length = 1;
            string res = origin.Substring(0, 1);
            origin = origin.Remove(0, 1);
            string et = "";
            for (int i = 0; i < times; i++)
            {
                length = char.ConvertToUtf32(res, res.Length - 1) % div + 1;
                et += origin.Substring(0, length);
                origin = origin.Remove(0, length);
                res += origin.Substring(0, length);
                origin = origin.Remove(0, length);
            }
            int etTail = 6 - et.Length;
            et += origin.Substring(origin.Length - etTail, etTail);
            origin = origin.Remove(origin.Length - etTail, etTail);
            res += origin;
            AddDictioanry("ET", et);
            return res;
        }

        #endregion

        #region 验证

        /// <summary>
        /// CRC校验
        /// </summary>
        public void VCRC()
        {
            try
            {
                SetTimer(true);
                string f = g_hash["F"];
                string b = g_hash["B"];
                SetTimer(true);
                string c1 = CommonOP.GetMappedSum(f, 2, 4);
                SetTimer(true);
                string c2 = CommonOP.GetMappedSum(f, 6, 4);
                SetTimer(true);
                string c3 = CommonOP.GetMappedSum(f, 0, 4);
                SetTimer(true);
                string c4 = CommonOP.GetMappedSum(b, 0, 4);
                if (f[0].ToString() != c1
                    || f[1].ToString() != c2
                    || b[3].ToString() != c3
                    || b[4].ToString() != c4)
                {
                    ThrowException();
                }
            }
            finally
            {
                SetTimer(false);
            }
        }
        /// <summary>
        /// 验证日期
        /// </summary>
        public void VExpire()
        {
            try
            {
                SetTimer(true);
                string et = g_hash["ET"];
                DateTime dt = new DateTime(int.Parse("20" + et.Substring(4)), int.Parse(et.Substring(2, 2)), int.Parse(et.Substring(0, 2)));
                if ((dt - DateTime.Now).TotalDays < 0)
                {
                    ThrowException();
                }
            }
            finally
            {
                SetTimer(false);
            }
        }
        /// <summary>
        /// 验证机器码
        /// </summary>
        /// <param name="toolCode">工具的代码</param>
        public void VMC(string toolCode)
        {
            try
            {
                SetTimer(true);
                string t = GetPCMC2(toolCode);
                string rc = g_hash["RC"];
                rc = rc.Remove(0, 2);
                rc = rc.Remove(rc.Length - 2);
                rc = RemoveExpire(rc);
                if (g_b64.Encode(t) != rc)
                {
                    ThrowException();
                }
            }
            finally
            {
                SetTimer(false);
            }
        }

        #endregion
    }
}
